/* charnoe.cpp
* Character Noe : class
*/
#include "charnoe.h"

//------------------------------------------------------------------------------
//- Class : Bullet
//------------------------------------------------------------------------------
Bullet::Bullet(int speedx, int speedy, int life, int damage) {
  _speedx = speedx;
  _speedy = speedy;
  _life = life;
  _damage = damage;
}
//------------------------------------------------------------------------------
//- Class : Weapon
//------------------------------------------------------------------------------
Weapon::Weapon(int id, int slot) {
  _id = id;
  _slot = slot;
  _standX[VIEW_RIGHT] = 66;
  switch(_id) {
   default: // Wep Colt
    _bulletY = 86;
    _standX[VIEW_LEFT] = 13;
    _standY = 54;
    _bulletAmount = 1;
    _bulletArr[0] = new Bullet(7, 0, 90, 1);
    _ammo = -1;
   break;
   case WEP_SHOTGUN:
    _bulletY = 85;
    _standX[VIEW_LEFT] = -4;
    _standY = 51;
    _bulletAmount = 3;
    _bulletArr[0] = new Bullet(8, -1, 90, 3);
    _bulletArr[1] = new Bullet(8, 0, 90, 3);
    _bulletArr[2] = new Bullet(8, 1, 90, 3);
    _ammo = 4;
   break;
  }
}

//------------------------------------------------------------------------------
//- Class : CharacterNoe
//------------------------------------------------------------------------------
/* Constructor 1
*
*/
CharacterNoe::CharacterNoe() : Character("data/CharacterNoe.cfg") {
  _spriteBuffer = create_bitmap(150, 150);
  _alphaBitmap = load_bitmap("images/charnoe/alpha.bmp", NULL);
  _keyPressed = 0;
  /* Bounding Box */
  __setBoundingBox(50, 0, 85, 110);
  __enableBoundingBox(1);
  __lockBoundingBox(1);


  /* Weapons */
  _weapons[0] = new Weapon(WEP_COLT, 0);
  _weapons[1] = 0x00;
  _weapons[2] = 0x00;
  _weapons[3] = 0x00;

  _mainWeapon = _weapons[0];
  _weaponPack = new AnimatedSprite();
  _weaponPack->__readFile("data/NoeWeapon.cfg");
  _weaponPack->__changeSequence(0);
  _weaponPack->__linkStatus(2, 0, 4); // Lets us know when can create the bullet
  _weaponPack->__linkStatus(2, 1, 2);

  /* HUD */
  _HUDWeapons = new HUD(122, 42);
  _HUDWeapons->__setX(8);
  _HUDWeapons->__setY(430);
  _HUDWeapons->_background = load_bitmap("images/hud/weapons/weapon_background.bmp", NULL);

  //_HUDAmmo = new HUD(30, 30);

  // <dev>
  _HUDWeapons->_elementArr[0] = new Sprite("images/hud/weapons/weapon_colt.bmp");
  _HUDWeapons->_idArr[0] = _weapons[0]->_slot;
  _HUDWeapons->_elementArr[0]->__move(2, 2);
  _HUDWeapons->_elementArr[4] = new Sprite("images/hud/weapons/weapon_selector.bmp");
  _HUDWeapons->_elementArr[4]->__move(1, 1);
  _HUDWeapons->__update();
  //</dev>

}

/* Destructor
*
*/
CharacterNoe::~CharacterNoe() {
  destroy_bitmap(_spriteBuffer);
  destroy_bitmap(_alphaBitmap);
  int i, j;
  for(i = 0; i < MAX_ANIMATION; ++i)
    for(j = 0; j < MAX_FRAME_PER_ANIMATION; ++j)
      if ( _bmpArr[i][j] ) destroy_bitmap(_bmpArr[i][j]);

  delete _HUDWeapons;
}
/* __readKeyboard() : main function to read any keyboard event
*
*/
void CharacterNoe::__readKeyboard() {
  // <dev>
  if ( key[KEY_RIGHT]) { // Moving Right
    __changeSequence(ANIMATION_2);
    _view = VIEW_RIGHT;
    __moveX(4);
    if ( __getX() + 92 > 640 ) __setX(GAME_W - 92);
  }
  if ( key[KEY_LEFT]) { // Moving Left
    _view = VIEW_LEFT;
    __moveX(-4);
    __changeSequence(ANIMATION_2);
    if ( __getX() + 52 < 0 ) __setX(-52);
  }
  if ( !key[KEY_RIGHT] && !key[KEY_LEFT] )
      __changeSequence(ANIMATION_1);

  if ( key[KEY_LCONTROL]) { // Firing
    if ( _status & STATUS_FIRING) return;
      _status |= STATUS_FIRING;
  }
  if ( key[KEY_X] && !(_keyPressed & 1) && !(_status & STATUS_FIRING) ) { // Switch
    __nextWeapon();
    _keyPressed |= 1;
  }
  if ( !key[KEY_X] && _keyPressed & 1 ) _keyPressed ^= 1;
  if ( key[KEY_SPACE] ) { // Jumping
    if ( _vec[1] == 0 ) _vec[1] += 14;
  }
}

/* __update() : update the character and its animation
*
*/
void CharacterNoe::__update() {
  // Character update
  __updateAnimation();

  // Jumping
  if ( _vec[1] != 0 ) {
    if ( _vec[1] > 0 ) { // Ascending Phase
      __moveY(_vec[1]);
      _vec[1] -= 1;
      if ( _vec[1] <= 0 ) _vec[1] = -1;
    }
    else { // Descending Phase
      __moveY(_vec[1]);
      if ( __getY() > GROUND_HEIGHT ) _vec[1] -= 2;
      else {
        __setY(GROUND_HEIGHT);
        _vec[1] = 0;
      }
    }
  }
  // Weapon update
  if ( _status & STATUS_FIRING ) { // The player was firing
    int status = _weaponPack->__updateAnimation();
    if ( status == 2) __fire (); // Create the bullet
    if ( status == 1 ) { // End of the animation
      _status ^= STATUS_FIRING;    // Removing Status with XOR
      _weaponPack->__resetSequence();
    }
  }
}
/* __fire()
*
*/
void CharacterNoe::__fire() {
  for(int i = 0; i < _mainWeapon->_bulletAmount; ++i) {
    Bullet * p = _mainWeapon->_bulletArr[i];
    Entity * bullet = new eShot(( _view == VIEW_RIGHT) ? p->_speedx : -p->_speedx, p->_speedy, p->_life, p->_damage);
    bullet->__setY(__getY() + _mainWeapon->_bulletY);
    bullet->__setX(__getX());
    if ( _view == VIEW_RIGHT ) bullet->__moveX(130);
    else bullet->__moveX(16);
    _entVec->push_back(bullet);
  }
  if ( _mainWeapon->_id != WEP_COLT ) {
    --_mainWeapon->_ammo;
    if ( _mainWeapon->_ammo < 1) { // no more ammos, so we switch
      int slot = _mainWeapon->_slot;
      _HUDWeapons->__deleteId(slot);
      delete _weapons[slot];
      _weapons[slot] = 0x00;
      __nextWeapon();
    }
  }
}
/*  __getSprite()
*
*/
BITMAP * CharacterNoe::__getSprite() {
  //<dev>
  clear_bitmap(_spriteBuffer);
  blit(_alphaBitmap, _spriteBuffer, 0, 0, 0, 0, _alphaBitmap->w, _alphaBitmap->h);
  if ( _view == VIEW_LEFT ) {
    draw_sprite_h_flip(_spriteBuffer, _weaponPack->__getSprite(),
    _mainWeapon->_standX[VIEW_LEFT], _mainWeapon->_standY);
    draw_sprite_h_flip(_spriteBuffer, _sprite, 0, 31);
  }
  else {
    draw_sprite(_spriteBuffer, _sprite, 0, 31);
    draw_sprite(_spriteBuffer, _weaponPack->__getSprite(),
    _mainWeapon->_standX[VIEW_RIGHT], _mainWeapon->_standY);
  }
  return _spriteBuffer;
  // </dev>
}

/* __nextWeapon()
*
*/
void CharacterNoe::__nextWeapon() {
  int i = 0;
  int slot = _mainWeapon->_slot;
  do {
    ++slot;
    ++i;
    if ( slot > 3 ) slot = 0;
    if ( i > 4 ) {
      allegro_message("Weapon system is corrupted");
      exit(-1);
    }
  } while(!_weapons[slot]);
  _mainWeapon = _weapons[slot];
  _weaponPack->__changeSequence(_mainWeapon->_id);
  _HUDWeapons->_elementArr[4]->__setX(1 + slot*30);
  _HUDWeapons->__update();
}
/*  __addWeapon()
*
*/
int CharacterNoe::__addWeapon(int wepid) {
  int i, slot;
  for(i = 0; i < 4; ++i)
    if ( _weapons[i] == 0x00 ) break;
  if ( i < 4 ) {
    slot = i;
    _weapons[i] = new Weapon(wepid, slot);
    for(i = 0; i < 4; ++i) {
      if ( _HUDWeapons->_idArr[i] == -1 ) {
        _HUDWeapons->_idArr[i] = slot;
        _HUDWeapons->_elementArr[i] = new Sprite("images/hud/weapons/weapon_shotgun.bmp");
        _HUDWeapons->_elementArr[i]->__move(2 + 30 * slot , 2);
        _HUDWeapons->__update();
        return slot;
      }
    }
  }
  return -1; // It failed
}
/*  __getItem()
*
*/
void CharacterNoe::__getItem(int id, int value1, int value2, int value3) {
  int i;
  switch(id) {
    case WEP_SHOTGUN:
      for(i = 0; i < 4; ++i)
        if ( _weapons[i] && _weapons[i]->_id == id ) break;
      if ( i < 4 ) // Player has the weapon already
        _weapons[id]->_ammo += value1;
      else {
        int slot = __addWeapon(id);
        if ( slot >= 0 ) _weapons[slot]->_ammo = value1;
      }
    break;
    case ITEM_HEALTH:
      __heal(value1);
    break;
  }
}

/* __linkHUD()
*
*/
void CharacterNoe::__linkHUD(vector<HUD *>* HUDVec) {
  HUDVec->push_back(_HUDWeapons);
  HUDVec->push_back(_HUDLife);
}
